import java.util.Random;
//根据老师的建议，进行的优化版本——把打印语句放在put 和 take 中，不用利用它们原有的锁，就可以，不用另外加锁打包原子操作。

public class Test5 {
    public static void main(String[] args) {
        Object lock = new Object();
        //创建一个队列
        MyBlockingQueue2 myBlockingQueue = new MyBlockingQueue2();
        Thread customer = new Thread(()->{
            while(true){
                try {
                    MyBlockingQueue2 myBlockingQueue2;
                    int cust = myBlockingQueue.take();
                    //System.out.println("消费了:"+cust+"，当前元素个数："+myBlockingQueue2.getSize());
                } catch (InterruptedException e) {
                    //throw new RuntimeException(e);
                    e.printStackTrace();
                }
            }

        },"customer");
        customer.start();
        Thread producer = new Thread(()->{
            Random random = new Random();
            while(true){
                int product = random.nextInt(100);
                try {
                    myBlockingQueue.put(product);
                    //System.out.println("产生了："+product+"，当前元素个数："+myBlockingQueue.getSize());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        },"producer");
        producer.start();
    }
}
class MyBlockingQueue2{
    Object lock = new Object();
    int[] strs = new int[1000];
    int size = 0;//有效元素个数
    int len = strs.length;
    int head = 0;
    int tail = 0;//tail指向的位置，应该是能放、要放元素的位置

    void put(int num) throws InterruptedException {
        synchronized (lock){
            while(size>=len){
                //队列满了
                //需要让这个代码能够实现阻塞:
                lock.wait();
            }
            strs[tail] = num;//放新元素

            tail++;
            if(tail>=len){
                tail = tail%len;
            }
            size++;
            System.out.println("产生了："+num+"，当前元素个数："+getSize());

            lock.notify();
        }
    }

    int take() throws InterruptedException {
        Integer n = null;
        synchronized (lock){
            while(size<=0){
                lock.wait();
            }

            n = strs[head];

            head ++;
            if(head>=len){
                head = 0;
            }
            size--;
            System.out.println("消费了:"+n+"，当前元素个数："+getSize());
            lock.notify();
        }
        return n;
    }

    int getSize(){
        return size;
    }
}